package com.ifonly.aop;

import com.ifonly.common.typeconverter.TypeConvert;

import java.lang.reflect.Method;

/**
 * @author <a href="mailto:ifonlymaster@163.com">ifonly</a>
 * @version 1.0 2015-12-09 17:35
 * @since JDK 1.6
 */
public class Invocation {

    protected Object target;
    protected Method method;
    protected Object[] args;
    protected Object result;

    private boolean isVoidType;

    public Invocation(Object target, Method method, Object... args) {
        this.target = target;
        this.method = method;
        this.args = args;
    }

    public void invoke() {
        try {
            isVoidType = (method.getReturnType() == Void.TYPE);

            if (isVoidType) {
                method.invoke(target, args);
            } else {
                result = method.invoke(target, args);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public Method getMethod() {
        return method;
    }

    public Object[] getArgs() {
        return args;
    }

    public Object getTarget() {
        return target;
    }

    public Object getResult() {
        if (isVoidType) {
            throw new UnsupportedOperationException("method return type is void: " + method);
        }
        return result;
    }

    @SuppressWarnings("unchecked")
    public <T> T getTypedResult() {
        return (T) TypeConvert.convert(method.getReturnType(), getResult());
    }

}
